package com.open.anim;

import android.animation.Animator;
import android.animation.TypeEvaluator;
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.util.Log;
import android.view.View;
import android.view.animation.Interpolator;

import com.open.anim.animator.AddAnimator;
import com.open.anim.animator.BaseAnimator;

/**
 * 动画管理类,进行动画的初始化设置(比如插值器,时间,各种动画效果集合等等)<p>
 * 动画效果集合:<br>
 * {@see com.open.anim.animator.AlphaAnimator}
 * {@see com.open.anim.animator.RotationAnimator}
 * {@see com.open.anim.animator.RotationXAnimator}
 * {@see com.open.anim.animator.RotationYAnimator}
 * {@see com.open.anim.animator.ScaleXAnimator}
 * {@see com.open.anim.animator.ScaleYAnimator}
 * {@see com.open.anim.animator.TranslationXAnimator}
 * {@see com.open.anim.animator.TranslationYAnimator}
 *
 * @Author: hailong.qiu 356752238@qq.com
 * @Maintainer: hailong.qiu 356752238@qq.com
 * @Date: 19-03-15
 * @Copyright: 2019 www.andriodtvdev.com Inc. All rights reserved.
 */
public class AnimatorManager implements LifecycleObserver {

    static final String TAG = "com.open.tvwidget";

    BaseAnimator baseAnimator = new AddAnimator();
    final OpenAnim mOpenAnim;
    final Lifecycle mLifecycle;

    boolean mIsStop = false; // 用于生命周期 stop 的时候，停止动画，再次恢复
    boolean mIsCancle = false; // 用户手动停止，生命 stop -> start，不再恢复

    /**
     * @param openAnim
     * @param lifecycle Activity,fragment 生命周期 监听
     */
    public AnimatorManager(
            OpenAnim openAnim,
            Lifecycle lifecycle) {
        mOpenAnim = openAnim;
        //
        if (null != openAnim) {
//            openAnim.registerAnimatorManager(this);
            interpolate(openAnim.getInterpolator());
            duration(openAnim.getDuration());
            typeEvaluator(openAnim.getTypeEvaluator());
        }
        if (null != lifecycle) {
            lifecycle.addObserver(this);
        }
        mLifecycle = lifecycle;
    }

    public BaseAnimator getAnimator() {
        return baseAnimator;
    }

    /**
     * 设置需要动画的view
     *
     * @param target View
     * @return AnimatorManager
     */
    public AnimatorManager into(Object target) {
        baseAnimator.setTarget(target);
        return this;
    }

    /**
     * 动画总耗时
     *
     * @param duration long
     * @return AnimatorManager
     */
    public AnimatorManager duration(long duration) {
        baseAnimator.setDuration(duration);
        return this;
    }

    /**
     * 执行动画的延时时间
     *
     * @param delay long
     * @return AnimatorManager
     */
    public AnimatorManager startDelay(long delay) {
        baseAnimator.setStartDelay(delay);
        return this;
    }

    /**
     * 设置插值器
     *
     * @param interpolator 插值器 Interpolator
     * @return AnimatorManager
     */
    public AnimatorManager interpolate(Interpolator interpolator) {
        baseAnimator.setInterpolator(interpolator);
        return this;
    }

    /**
     * 并行执行动画集合
     *
     * @param items {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator items}
     * @return AnimatorManager
     */
    public AnimatorManager together(BaseAnimator... items) {
        baseAnimator.playTogether(items);
        return this;
    }

    /**
     * 使用 res/anim 下的 XML属性动画支持
     *
     * @param items 动画 ID 集合
     * @return AnimatorManager
     */
    public AnimatorManager together(int... items) {
        baseAnimator.playTogether(mOpenAnim.getContext(), items);
        return this;
    }

    /**
     * 顺序执行动画集合
     *
     * @param items {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator items}
     * @return AnimatorManager
     */
    public AnimatorManager sequentially(BaseAnimator... items) {
        baseAnimator.playSequentially(items);
        return this;
    }

    /**
     * 一般配合<br>
     * {@linkplain #before(BaseAnimator) before(将现有动画插入到传入的动画之前执行)},<br>
     * {@linkplain #after(BaseAnimator) after(将现有动画插入到传入的动画之后执行)},<br>
     * {@linkplain #with(BaseAnimator) with(将现有动画和传入的动画同时执行)} 使用,也可以执行单个动画
     *
     * <pre>
     * {@code
     * 几种常用例子:
     * .play(anim1).with(anim2)
     * .play(anim1).after(anim2)
     * .play(anim1).before(anim2)
     * .play(anim1).with(anim2).after(anim3)
     * .play(anim1).with(anim2).before(anim3)
     * .play(anim1).after(anim2).before(anim3)
     * .play(anim1).before(anim2).after(anim3)
     * }
     * </pre>
     *
     * @param item {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator item}
     * @return AnimatorManager
     */
    public AnimatorManager play(BaseAnimator item) {
        baseAnimator.play(item);
        return this;
    }

    /**
     * 将现有动画插入到传入的动画之前执行
     * 配合 {@link #play(BaseAnimator)} 使用
     *
     * @param item {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator item}
     * @return AnimatorManager
     */
    public AnimatorManager before(BaseAnimator item) {
        baseAnimator.before(item);
        return this;
    }

    /**
     * 将现有动画插入到传入的动画之后执行
     * 配合 {@link #play(BaseAnimator)} 使用
     *
     * @param item {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator item}
     * @return AnimatorManager
     */
    public AnimatorManager after(BaseAnimator item) {
        baseAnimator.after(item);
        return this;
    }

    /**
     * 将现有动画和传入的动画同时执行
     * 配合 {@link #play(BaseAnimator)} 使用
     *
     * @param item {@linkplain com.open.anim.animator.BaseAnimator BaseAnimator item}
     * @return AnimatorManager
     */
    public AnimatorManager with(BaseAnimator item) {
        baseAnimator.with(item);
        return this;
    }

    /**
     * 开始执行动画
     *
     * @return AnimatorManager
     */
    public AnimatorManager start() {
        baseAnimator.startAnim();
        mIsCancle = false;
        return this;
    }

    /**
     * 取消动画
     *
     * @return AnimatorManager
     */
    public AnimatorManager cancel() {
        baseAnimator.cancelAnim();
        mIsCancle = true;
        return this;
    }

    /**
     * 重复执行动画次数
     *
     * @param repeatCount 默认为0,ValueAnimator.INFINITE 一直重复，其它数字(0~N)为动画重复次数
     * @return AnimatorManager
     */
    public AnimatorManager repeatCount(int repeatCount) {
        baseAnimator.setRepeatCount(repeatCount);
        return this;
    }

    /**
     * 重复执行模式
     *
     * @param repeatMode ValueAnimator.RESTART 表示从头开始 | INFINITE 重复多次 | REVERSE 从末尾倒播
     * @return AnimatorManager
     */
    public AnimatorManager repeatMode(int repeatMode) {
        baseAnimator.setRepeatMode(repeatMode);
        return this;
    }

    /**
     * 属性动画计算器，控制动画如何过渡的
     *
     * @param value TypeEvaluator
     * @return AnimatorManager
     */
    public AnimatorManager typeEvaluator(TypeEvaluator value) {
        baseAnimator.setTypeEvaluator(value);
        return this;
    }

    /**
     * 添加动画监听函数
     *
     * @param cb
     * @return
     */
    public AnimatorManager addListener(OpenAnimatorListener cb) {
        baseAnimator.addAnimListener(cb);
        return this;
    }

    /**
     * 生命周期onStart
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        Log.d(TAG, "life onStart");
        if (mIsStop && !mIsCancle) {
            baseAnimator.startAnim();
            mIsStop = false;
        }
    }

    /**
     * 生命周期onStop
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void onStop() {
        Log.d(TAG, "life onStop");
        baseAnimator.cancelAnim();
        mIsStop = true;
    }

    /**
     * 生命周期onDestroy，销毁一些东西
     */
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
        Log.d(TAG, "life onDestroy" + this);
        baseAnimator.cancelAnim();
        baseAnimator.removeAllListener();
//        mOpenAnim.unregisterAnimatorManager(this);
        if (mLifecycle != null) {
            mLifecycle.removeObserver(this);
        }
    }

    /**
     * 动画监听回调
     */
    public static class OpenAnimatorListener implements Animator.AnimatorListener {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    }

}
